﻿using System;
using System.Web;
using System.Collections.Specialized;

namespace Daco.Web
{
    public interface IUrlBuilder
    {
        /// <summary>
        /// Builds path for calling page with URL argument as the parameter.
        /// </summary>
        /// <param name="url">
        /// URL to use as a parameter.
        /// </param>
        /// <returns>
        /// URL to calling page with URL argument as page's parameter with escaped characters to make it valid parameter.
        /// </returns>
        string BuildUrl(string url);

        /// <summary>
        /// Builds a "Full URL" (server + path) for calling page with URL argument as parameter.
        /// </summary>
        /// <param name="url">
        /// URL to use as a parameter.
        /// </param>
        /// <returns>
        /// URL to calling page with URL argument as page's parameter with escaped characters to make it valid parameter.
        /// </returns>
        string BuildUrlFull(string url);
    }

    public class CUrlBuilder : IUrlBuilder
    {
        /// <summary>
        /// The _base urls.
        /// </summary>
        private static readonly StringDictionary _baseUrls = new StringDictionary();

        /// <summary>
        /// Gets ScriptName.
        /// </summary>
        public static string ScriptName
        {
            get
            {
                string scriptName = HttpContext.Current.Request.FilePath.ToLower();
                return scriptName.Substring(scriptName.LastIndexOf('/') + 1);
            }
        }

        /// <summary>
        /// Gets ScriptNamePath.
        /// </summary>
        public static string ScriptNamePath
        {
            get
            {
                string scriptName = HttpContext.Current.Request.FilePath.ToLower();
                return scriptName.Substring(0, scriptName.LastIndexOf('/'));
            }
        }
        public static string BaseUrl
        {
            get
            {
                string baseUrl = string.Empty;
                try
                {
                    // Lookup the AppRoot based on the current path. 
                    baseUrl = _baseUrls[HttpContext.Current.Request.FilePath];
                    if (string.IsNullOrEmpty(baseUrl))
                    {
                        baseUrl = TreatBaseUrl(Config.CSiteConfig.Current.BaseUrl);
                    }
                    // save to cache
                    _baseUrls[HttpContext.Current.Request.FilePath] = baseUrl;
                }
                catch (Exception) { baseUrl = string.Empty; }

                return baseUrl;
            }
        }

        /// <summary>
        /// Gets Path.
        /// </summary>
        public static string Path
        {
            get
            {
                return TreatPathStr(Config.CSiteConfig.Current.AppRoot);
            }
        }

        /// <summary>
        /// The treat base url.
        /// </summary>
        /// <param name="baseUrl">
        /// The base url.
        /// </param>
        /// <returns>
        /// The treat base url.
        /// </returns>
        protected static string TreatBaseUrl(string baseUrl)
        {
            if (baseUrl.EndsWith("/"))
            {
                // remove ending slash...
                baseUrl = baseUrl.Remove(baseUrl.Length - 1, 1);
            }

            return baseUrl;
        }

        /// <summary>
        /// The treat path str.
        /// </summary>
        /// <param name="altRoot">
        /// The alt root.
        /// </param>
        /// <returns>
        /// The treat path str.
        /// </returns>
        protected static string TreatPathStr(string altRoot)
        {
            string _path = string.Empty;

            try
            {
                _path = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;

                if (!_path.EndsWith("/"))
                {
                    _path += "/";
                }

                if (!String.IsNullOrEmpty(altRoot))
                {
                    // use specified root
                    _path = altRoot;

                    if (_path.StartsWith("~"))
                    {
                        // transform with application path...
                        _path = _path.Replace("~", System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);
                    }

                    if (_path[0] != '/')
                    {
                        _path = _path.Insert(0, "/");
                    }
                }

                if (!_path.EndsWith("/"))
                {
                    _path += "/";
                }

                // remove redundant slashes...
                while (_path.Contains("//"))
                {
                    _path = _path.Replace("//", "/");
                }
            }
            catch (Exception)
            {
                _path = "/";
            }

            return _path;
        }
        #region IUrlBuilder Members

        public string BuildUrl(string url)
        {
            // escape & to &amp;
            url = url.Replace("&", "&amp;");

            // return URL to current script with URL from parameter as script's parameter
            //return String.Format("{0}{1}?{2}", Path, ScriptName, url);
            return string.Format("{0}{1}", Path, url);
        }

        public string BuildUrlFull(string url)
        {
            // append the full base server url to the beginning of the url (e.g. http://mydomain.com)
            return String.Format("{0}{1}", BaseUrl, BuildUrl(url));
        }

        #endregion
    }
}
